/**
 * Title:       SecurityModule.java
 * Copyright:   Copyright (c) 1996-2004 The Agent Factory Working Group. All rights reserved.
 * Licence:     This file is free software; you can redistribute it and/or modify
 *              it under the terms of the GNU Lesser General Public License as published by
 *              the Free Software Foundation; either version 2.1, or (at your option)
 *              any later version.
 *
 *              This file is distributed in the hope that it will be useful,
 *              but WITHOUT ANY WARRANTY; without even the implied warranty of
 *              MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *              GNU Lesser General Public License for more details.
 *
 *              You should have received a copy of the GNU Lesser General Public License
 *              along with Agent Factory; see the file COPYING.  If not, write to
 *              the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 *              Boston, MA 02111-1307, USA.
 */
package com.agentfactory.platform.service;

import java.util.*;
import com.agentfactory.platform.core.Agent;

/**
 * This class implements a security model for the platform services.  It associates each service with
 * a unique policy that is specified via the AFPolicy class.
 *
 * @author  Rem Collier
 */
public class SecurityModule {
    private HashMap services;
    
    /** Creates a new instance of SecurityModule */
    public SecurityModule(Vector policies) {
        services = new HashMap();
        
        // Process the security settings as specified in the Platform Configuration Script
        int right = -1;
        String line = null, name = null, service = null, policy = null;
        StringTokenizer tok = null;
        for (int i = 0; i < policies.size(); i++) {
            line = (String) policies.get(i);
            tok = new StringTokenizer(line, " ");
            tok.nextToken(); // ignore the first token as it is SECURITY_POLICY
            policy = tok.nextToken();
            if (policy.equalsIgnoreCase("ALLOW")) {
                right = AFRight.ALLOW;
            } else {
                right = AFRight.DENY;
            }
            name = tok.nextToken();
            service = tok.nextToken();
            if (name.equals("*")) {
                //System.out.println("[SecurityModule] Setting global access policy for " + service + "{" + policy + "}");
                // This is the global policy
                addGlobalPolicy(service, right);
            } else {
                //System.out.println("[SecurityModule] Setting access policy for " + service + "{" + name + "," + policy + "}");
                addPolicy(name, service, right);
            }
        }
    }

    /**
     * This method checks whether or not an agent has access
     * to a service.  To achieve this, it locates the relevant
     * security policy and checks that policy.  If no policy
     * exists, then the default response is that the agent has
     * access to the service.
     *
     * @param agent the name of the agent that is requesting the service
     * @param service the service being requested
     */
    public boolean hasAccess(String agent, String service) {
        AFPolicy policy = (AFPolicy) services.get(service);
        if (policy != null) {
            return policy.hasAccess(agent);
        }
        return true;
    }
    
    /**
     * Adds an agent right to a service policy.  If no policy currently
     * exists for the service, then the agent creates a new policy whose 
     * global right is DENY.
     *
     * Here the agent is specified by a reference to the underlying agent
     * object.  This should be used only for the creation of the System
     * Agents.
     *
     * @param agent the agent that will be given the right
     * @param service the service they associated with the right.
     * @param right the right they are given
     */
    public void addPolicy(Agent agent, String service, int right) {
        AFPolicy policy = (AFPolicy) services.get(service);
        
        if (policy == null) {
            policy = new AFPolicy(AFRight.DENY);
            services.put(service, policy);
        }
        
        policy.addRight(agent, right);
    }

    /**
     * Adds an agent right to a service policy.  If no policy currently
     * exists for the service, then the agent creates a new policy whose 
     * global right is DENY.
     *
     * Here the agent is specified by the name of the agent.
     *
     * @param name the agent that will be given the right
     * @param service the service they associated with the right.
     * @param right the right they are given
     */
    public void addPolicy(String name, String service, int right) {
        AFPolicy policy = (AFPolicy) services.get(service);
        
        if (policy == null) {
            policy = new AFPolicy(AFRight.DENY);
            services.put(service, policy);
        }
        
        policy.addRight(name, right);
    }

    public void addGlobalPolicy(String service, int right) {
        AFPolicy policy = (AFPolicy) services.get(service);
        
        if (policy == null) {
            policy = new AFPolicy(right);
            services.put(service, policy);
        } else {
            policy.setGlobalPolicy(right);
        }
    }
}
